 package TAIC.IPLM;
import java.io.*;
import java.util.*; 

public class CodeBookGen {
	static public void main ( String str[] 	) throws Exception {
		if (  str.length != 3 ) {
			System.out.println ( "please input the config file, the corresponding file and desFile (train.mat)") ;
			return ;
		}
		( new CodeBookGen()).generateCodeBook(str [ 0 ], str[ 1 ], str[ 2 ]);
	}
	
	public void generateCodeBook ( String configFile , String corFile, String dstFile ) throws Exception{
		Scanner configScanner = new Scanner ( new File ( configFile )) ; 
		Node [] datasets = new Node [ configScanner.nextInt() ];
		int totalVec = 0 ;
		int desiredVec = configScanner.nextInt() ; configScanner.nextLine () ; 
		for ( int i = 0 ; i < datasets.length ; i ++ ){
			datasets [ i ] = new Node () ; 
			datasets [ i ].path = configScanner.nextLine().trim() + "\\";
			File tempfile = new File ( datasets[i].path) ; 
			if ( !tempfile.exists() ) {
				System.out.println ( "Folder " + datasets[i].path + " does not exist") ;
				return ; 
			}
			Scanner imageScanner = new Scanner ( new File ( datasets[ i ].path + "ImageCorpus.txt"));
			while( imageScanner.hasNextInt () ) {
				imageScanner.nextInt() ; imageScanner.nextInt() ;
				String str = imageScanner.nextLine().trim() +".sift_o" ;
				if ( str.indexOf( ':')== -1 ) str = datasets [ i ].path + str ;
				File iFile = new File (  str );
				if ( !iFile.exists() ) continue ; 
				Scanner tempScanner = new Scanner ( iFile ) ;
				if ( tempScanner.hasNextInt() ) datasets[ i ].oriSize +=  tempScanner.nextInt() ;
				tempScanner.close() ;
			}
			totalVec += datasets[ i ].oriSize ;
			imageScanner.close() ; 
		}
		
		PrintStream pathOut = new PrintStream ( new File ( corFile ) ) ;

		Vector < String >codeBook = new Vector < String > ( desiredVec + 5000 ) ;  
		//Vector < String >pathBook = new Vector < String > ( desiredVec + 5000 ) ;  
		double ratio = (double)desiredVec / totalVec ;
		if ( ratio > 1 ) ratio = 1.0 ;
		for ( int i = 0 ; i < datasets.length ; i ++ ) {
			Scanner scanner = new Scanner ( new File ( datasets[ i ].path + "ImageCorpus.txt"));
			while ( scanner.hasNextInt() ) {
				scanner.nextInt() ;scanner.nextInt() ;
				String siftFile = scanner.nextLine().trim() +".sift_o" ;
				if ( siftFile.indexOf( ':')== -1 ) siftFile = datasets [ i ].path + siftFile ;
				File iFile = new File ( siftFile );
				if ( !iFile.exists() ) continue ; 
				Scanner imageScanner = new  Scanner ( iFile ) ;
				if ( ! imageScanner.hasNextInt() ) continue ;
				int vecsize = imageScanner.nextInt() ;   //   total vectors in image
				imageScanner.nextLine(); 
				//String [] str = new String [ vecsize ] ; 
				boolean [] used = new boolean [ vecsize ]; 
				int extsize = toInt ( ratio * vecsize ) ;  // number of vector to random extract 
				for ( int j = 0;  j < extsize ; j ++ ) {
					int temp = random.nextInt( vecsize ) ;
					if ( used [ temp ]) j -- ;
					used [ temp ] = true ;
				}
				try {
					for ( int j = 0 ; j < vecsize ; j ++ ) {
						if ( ! imageScanner.hasNextDouble () ) break ; 
						if ( used [ j ] ) {
							pathOut.print ( siftFile + " " + j ) ; 
							for ( int k = 0 ; k < 4 ; k++ ) pathOut.println ( " " + imageScanner.nextDouble() );
							codeBook.add( imageScanner.nextLine().trim()) ;
						}
						else imageScanner.nextLine() ;
					}
				}catch (Exception e ) {
					System.out.println ( siftFile ); 
					e.printStackTrace() ; 
				}
				imageScanner.close () ; 
			}
		}
		pathOut.close() ;		

		PrintStream fout = new PrintStream ( new File ( dstFile ) ) ;
		fout.println ( codeBook.size() + " 128" ) ;
		for ( int i =0 ; i < codeBook.size() ; i ++ ) fout.println ( codeBook.get(i) ) ;
		fout.close() ;
	}
	
	
	int toInt ( double d ){
		return Math.round((float)Math.ceil(d)) ;
	}
	
	public class Node  {
		String path ;
		int oriSize ;
		int extSize ; 
	}
		
	static Random random = new Random () ;
}
